/*
 * @Descripttion: uuid引用全局预制体替换，单个预制替换，操作撤销
 * @version: 
 * @Author: 周志伟
 * @Date: 2021-07-05 11:18:30
 * @LastEditors: 周志伟
 * @LastEditTime: 2021-07-07 16:40:49
 */

'use strict';
const Fs = require("fire-fs")
const Path = require('path');
const ConfigManager = require("./config-manager");
const whiteList = [
  "api",
  "componentLib",
  "effect",
  "framework",
  "resources",
  "scenes",
  "shark",
  "sharkSelectQuestion",
  "template",
]

module.exports = {
  load() {
    // execute when package loaded
  },

  unload() {
    // execute when package unloaded
  },

  // register your ipc messages here
  messages: {
    'open'() {
      // open entry panel registered in package.json
      Editor.Panel.open('zzw_uuid_replace');
    },
    'say-hello'() {
      Editor.log('Hello World!');
      // send ipc message to panel
      Editor.Ipc.sendToPanel('zzw_uuid_replace', 'zzw_uuid_replace:hello');
    },
    'open-replace-uuid'() {
      Editor.log('打开 uuid替换面板');
      Editor.Panel.open(`zzw_uuid_replace`);
    },
    /**
     * 开始替换
     * @param {*} evt 
     * @param {*} config 存储新旧uuid
     */

    'start-replace-uuid'(evt, config) {
      this.initRecord(config);
      this.getAllPrefab(config);
    },
    /**
     * 撤销上一步操作
     */
    'back-replace-uuid'() {
      const _config = ConfigManager.read();
      let record = _config.record[_config.record.length - 1];
      for (let i = 0; i < record.length; i++) {
        this.saveAndRefreshData(record[i].url, record[i].prefabInfo);
        Editor.log("*****************************撤销" + (i + 1) + "个******************************");
      }
      let newRecord = _config.record.slice(0, _config.record.length - 1);
      _config.record = newRecord;
      ConfigManager.writeFile(_config);
      Editor.log("*****************************撤销 完成******************************");
    }
  },

  getAllPrefab(config) {
    let old_uuid = Editor.Utils.UuidUtils.compressUuid(config.oldUuid);
    let new_uuid = Editor.Utils.UuidUtils.compressUuid(config.newUuid);
    let _prefabUuid = config.prefabUuid;
    if (_prefabUuid) {
      //预制体内替换
      Editor.log("**********单个预制*******开始  替换********************");
      let _path = Editor.assetdb.uuidToFspath(_prefabUuid);
      this.replaceUuid(_path, old_uuid, new_uuid);
      if (this.recordConfig.record.length > 0) {
        ConfigManager.save(this.recordConfig);
      }
      Editor.log("************************替换  结束******************** ");
    } else {
      //全局替换
      let self = this;
      Editor.assetdb.queryAssets("db://assets/**/*", "prefab", function (err, assetInfo) {
        Editor.log("***********全  部*************开始替换 ********************");
        assetInfo.forEach(function (info) {
          let ischeck = false;
          let idx2 = info.url.indexOf("assets");
          for (let i = 0; i < whiteList.length; i++) {
            let idx1 = info.url.indexOf(whiteList[i]);
            if (idx2 + "assets".length == idx1 - 1) {
              ischeck = true;
            }
          }
          if (!ischeck) {
            self.replaceUuid(info.path, old_uuid, new_uuid);
          }

        })
        if (self.recordConfig.record.length > 0) {
          ConfigManager.save(self.recordConfig);
        }
        Editor.log("************************替换    结束******************** ");
      })
    }

  },

  /**
   * 替换uuid
   * @param {*} path 预制路径
   * @param {*} old_uuid  旧的uuid
   * @param {*} new_uuid  新的uuid
   */
  replaceUuid(path, old_uuid, new_uuid) {
    let jsonInfo = Fs.readJsonSync(path);
    var oldjsonInfo = JSON.parse(JSON.stringify(jsonInfo));
    const assetInfo = Editor.assetdb.assetInfoByPath(path);
    const url = assetInfo.url;

    let _jsonInfo = jsonInfo;
    let len = _jsonInfo.length;
    let idx = 0;
    for (let i = 0; i < len; i++) {
      if (_jsonInfo[i].__type__ == old_uuid) {
        _jsonInfo[i].__type__ = new_uuid;
        idx++;
      } else if (jsonInfo[i].__type__ == "cc.ClickEvent") {
        if (_jsonInfo[i]._componentId === old_uuid) {
          _jsonInfo[i]._componentId = new_uuid;
          idx++;
        }
      }
    }
    if (idx > 0) {
      this.saveRecord(oldjsonInfo, url);
      Editor.error(url);
      this.saveAndRefreshData(url, _jsonInfo);
      Editor.log("*****************************替换" + idx + "个******************************");
    }
  },
  /**
   * 数据保存和刷新
   * @param {} url 
   * @param {*} jsonInfo 
   */
  saveAndRefreshData(url, jsonInfo) {
    Editor.assetdb.saveExists(url, JSON.stringify(jsonInfo, null, 2), (e, m) => {
    });
    Editor.assetdb.refresh(url, function (err, results) { });
  },
  /**
   * 初始化记录配置文件
   * @param {} config 
   */
  initRecord(config) {
    this.recordConfig = {
      prefabUuid: config.prefabUuid,
      oldUuid: config.oldUuid,
      newUuid: config.newUuid,
      record: []
    }
  },
  /**
   * 保存操作记录
   * @param {} jsonInfo 
   * @param {*} url 
   */
  saveRecord(jsonInfo, url) {
    let _record = {
      prefabInfo: jsonInfo,
      url: url
    }
    this.recordConfig.record.push(_record);
  },
  /**
    * 遍历文件/文件夹并执行函数
    * @param {Fs.PathLike} path 路径
    * @param {(filePath: Fs.PathLike, stat: Fs.Stats) => void} handler 处理函数
    */
  map(path) {
    if (!Fs.existsSync(path)) return
    const names = Fs.readdirSync(path);
    const documentArr = [];
    for (const name of names) {
      let _path = Path.join(path, name);
      if (Fs.existsSync(_path)) {
        const stats1 = Fs.lstatSync(_path);
        if (stats1.isDirectory()) {
          const name1 = name.replace(/\s+/g, "");
          let obj = {
            name: name1,
            path: _path
          }
          documentArr.push(obj);
        }
      }
    }
    return documentArr;
  }
};